package com.chart.web.controller.aliPay;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeQueryModel;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.request.AlipayTradePrecreateRequest;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.response.AlipayTradePagePayResponse;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.chart.common.core.domain.AjaxResult;
import com.chart.common.utils.QRCodeUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;

@Component
public class AlipayUtil {

    @Value("${alipay.appid}")
    private String appid;
    @Value("${alipay.url}")
    private String url;
    @Value("${alipay.privateKey}")
    private String privateKey;
    @Value("${alipay.publicKey}")
    private String publicKey;

    @Value("${alipay.alipayPublicKey}")
    private String alipayPublicKey;
    @Value("${alipay.merchantPrivateKey}")
    private String merchantPrivateKey;


    @Value("${alipay.charset}")
    private String charset;
    @Value("${alipay.signType}")
    private String signType;

    @Value("${alipay.format}")
    private String format;

    @Value("${alipay.notifyUrl}")
    private String notifyUrl;
    @Value("${alipay.returnUrl}")
    private String returnUrl;


    public void pay(String id, String price, String title, HttpServletResponse response) throws IOException {
        AlipayClient alipayClient = new DefaultAlipayClient(
                url, appid, privateKey, "json", "GBK", alipayPublicKey, "RSA2"
        );
        AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();

        JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no", id);
        bizContent.put("total_amount", price);
        bizContent.put("subject", title);
        bizContent.put("product_code", "FACE_TO_FACE_PAYMENT");
        request.setBizContent(bizContent.toString());


        try {
            AlipayTradePrecreateResponse alipayResponse = alipayClient.execute(request);
            if (alipayResponse.isSuccess()) {
                System.out.println("调用成功");

                String qrCodeUrl = alipayResponse.getQrCode();
                System.out.println("二维码路径: " + qrCodeUrl);

                // 设置响应内容类型为图片
                response.setContentType("image/png");

                // 获取输出流并生成二维码
                ServletOutputStream outputStream = response.getOutputStream();
                QRCodeUtils.encode(qrCodeUrl, outputStream);
                outputStream.flush();
            } else {
                System.out.println("调用失败");
                response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "调用失败");
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
            response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "调用异常");
        } catch (IOException e) {
            throw new RuntimeException(e);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    private String convertCentsToYuan(String priceInCents) {
        // 将分转换为元，并保留两位小数
        BigDecimal priceInYuan = new BigDecimal(priceInCents).divide(new BigDecimal(100));
        return priceInYuan.setScale(2, RoundingMode.HALF_UP).toString();
    }


    /**
     * 支付宝当面付支付接口
     *
     * @param id
     * @param priceInCents
     * @param title
     * @return
     * @throws AlipayApiException
     */
    public String aliPayText(String id, String priceInCents, String title) throws AlipayApiException {
        // 转换金额：将分转换为元
        String price = convertCentsToYuan(priceInCents);
        AlipayClient alipayClient = new DefaultAlipayClient(
                url, appid, privateKey, "json", charset, alipayPublicKey, signType
        );
        AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();

        // 设置回调地址
        request.setNotifyUrl(notifyUrl);

        JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no", id);
        bizContent.put("total_amount", price);
        bizContent.put("subject", title);
        bizContent.put("product_code", "FACE_TO_FACE_PAYMENT");
        request.setBizContent(bizContent.toString());

        AlipayTradePrecreateResponse alipayResponse = alipayClient.execute(request);
        if (alipayResponse.isSuccess()) {
            System.out.println("调用成功");
            return alipayResponse.getQrCode();
        } else {
            System.out.println("调用失败");
            throw new AlipayApiException("调用失败，错误信息：" + alipayResponse.getSubMsg());
        }
    }

    /**
     * 支付宝自定义支付
     *
     * @param id
     * @param priceInCents
     * @param title
     * @return
     * @throws AlipayApiException
     */

    public String customPayment(String id, String priceInCents, String title) throws AlipayApiException {

        AlipayClient alipayClient = new DefaultAlipayClient(
                url, appid, privateKey, "json", charset, alipayPublicKey, signType
        );
        AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();

        // 设置回调地址
        request.setNotifyUrl(notifyUrl);

        JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no", id);
        bizContent.put("total_amount", priceInCents);
        bizContent.put("subject", title);
        bizContent.put("product_code", "FACE_TO_FACE_PAYMENT");
        request.setBizContent(bizContent.toString());

        AlipayTradePrecreateResponse alipayResponse = alipayClient.execute(request);
        if (alipayResponse.isSuccess()) {
            System.out.println("调用成功");
            return alipayResponse.getQrCode();
        } else {
            System.out.println("调用失败");
            throw new AlipayApiException("调用失败，错误信息：" + alipayResponse.getSubMsg());
        }
    }

    public String aliPay(String id, String priceInCents, String title) throws AlipayApiException {
        // 转换金额：将分转换为元
        String price = convertCentsToYuan(priceInCents);
        AlipayClient alipayClient = new DefaultAlipayClient(
                url, appid, privateKey, "json", "GBK", alipayPublicKey, "RSA2"
        );
        AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
        request.setNotifyUrl(notifyUrl);
        JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no", id);
        bizContent.put("total_amount", price);
        bizContent.put("subject", title);
        bizContent.put("product_code", "FACE_TO_FACE_PAYMENT");
        request.setBizContent(bizContent.toString());

        AlipayTradePrecreateResponse alipayResponse = alipayClient.execute(request);
        if (alipayResponse.isSuccess()) {
            System.out.println("调用成功");
            return alipayResponse.getQrCode();
        } else {
            System.out.println("调用失败");
            throw new AlipayApiException("调用失败，错误信息：" + alipayResponse.getSubMsg());
        }
    }


    public String pay(String id, String price, String title) {
        AlipayClient alipayClient = new DefaultAlipayClient(url, appid, privateKey, "json", "GBK", alipayPublicKey, "RSA2");
        AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
        //        设置支付成功后的回调地址，改地址必须外网可以访问到才行，所以调试该步骤必须要在外网环境，否则会出现支付成功但是却不能回调
//        request.setNotifyUrl("");

        JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no", id);
        bizContent.put("total_amount", price);
        bizContent.put("subject", title);
//        bizContent.put("product_code", "FAST_INSTANT_TRADE_PAY");
        bizContent.put("product_code", "FACE_TO_FACE_PAYMENT");
        request.setBizContent(bizContent.toString());

        AlipayTradePrecreateResponse response;
        try {
            response = alipayClient.execute(request);
            if (response.isSuccess()) {
                System.out.println("调用成功");
                String qr_code = response.getQrCode();
                // 需要修改为运行机器上的路径
                String filePath = String.format("d:/qr-%s.png",
                        response.getOutTradeNo());
                System.out.println("filePath:" + filePath);
                return qr_code;
            } else {
                System.out.println("调用失败");
                return "调用失败";
            }
        } catch (AlipayApiException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return "调用异常";
        }
    }


    public String query(String id) {
        AlipayClient alipayClient = new DefaultAlipayClient(url, appid, privateKey, "json", "UTf-8", publicKey, "RSA2");
        AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
        JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no", id);
        request.setBizContent(bizContent.toString());
        AlipayTradeQueryResponse response = null;
        String body = null;
        try {
            response = alipayClient.execute(request);
            body = response.getBody();
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        if (response.isSuccess()) {
            System.out.println("调用成功");
        } else {
            System.out.println("调用失败");
        }
        return body;
    }


    //回调函数
    public String code(String id, String price, String title) {
        AlipayClient alipayClient = new DefaultAlipayClient(url, appid, privateKey, "json", "UTf-8", publicKey, "RSA2");
        AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
        request.setNotifyUrl(notifyUrl);
        request.setReturnUrl(returnUrl);
        JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no", id);
        bizContent.put("total_amount", price);
        bizContent.put("subject", title);
        bizContent.put("product_code", "FAST_INSTANT_TRADE_PAY");

        request.setBizContent(bizContent.toString());
        AlipayTradePagePayResponse response = null;
        String form = null;
        try {
            response = alipayClient.pageExecute(request);
            form = response.getBody();
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        if (response.isSuccess()) {
            System.out.println("调用成功");
        } else {
            System.out.println("调用失败");
        }
        return form;
    }

    /**
     * 支付宝当面付查询订单状态
     *
     * @param
     * @return
     * @throws AlipayApiException
     */
    public AjaxResult queryOrder(String outTradeNo) throws AlipayApiException {
        // 初始化SDK
        AlipayClient alipayClient = new DefaultAlipayClient(url, appid, privateKey, "json", "UTf-8", alipayPublicKey, "RSA2");

        // 构造请求参数以调用接口
        AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
        AlipayTradeQueryModel model = new AlipayTradeQueryModel();

        // 设置订单支付时传入的商户订单号
        model.setOutTradeNo(outTradeNo);

        // 设置支付宝交易号
        //  model.setTradeNo(outTradeNo);

        // 设置查询选项
        List<String> queryOptions = new ArrayList<String>();
        queryOptions.add("trade_settle_info");
        model.setQueryOptions(queryOptions);

        request.setBizModel(model);
        // 第三方代调用模式下请设置app_auth_token
        // request.putOtherTextParam("app_auth_token", "<-- 请填写应用授权令牌 -->");

        AlipayTradeQueryResponse response = alipayClient.execute(request);
        System.out.println(response.getBody());

        if (response.isSuccess()) {
            System.out.println("调用成功");
        } else {
            System.out.println("调用失败");
            // sdk版本是"4.38.0.ALL"及以上,可以参考下面的示例获取诊断链接
            // String diagnosisUrl = DiagnosisUtils.getDiagnosisUrl(response);
            // System.out.println(diagnosisUrl);
        }
        return AjaxResult.success(response);
    }

    /**
     * 支付宝当面付查询订单状态
     *
     * @param tradeNo
     * @return
     * @throws AlipayApiException
     */
    public String queryOrderTwo(String outTradeNo) throws AlipayApiException {
        // 初始化SDK
        AlipayClient alipayClient = new DefaultAlipayClient(url, appid, privateKey, "json", "UTf-8", alipayPublicKey, "RSA2");

        // 构造请求参数以调用接口
        AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
        AlipayTradeQueryModel model = new AlipayTradeQueryModel();

        // 设置订单支付时传入的商户订单号
        model.setOutTradeNo(outTradeNo);

        // 设置支付宝交易号
        //  model.setTradeNo(outTradeNo);

        // 设置查询选项
        List<String> queryOptions = new ArrayList<String>();
        queryOptions.add("trade_settle_info");
        model.setQueryOptions(queryOptions);

        request.setBizModel(model);
        // 第三方代调用模式下请设置app_auth_token
        // request.putOtherTextParam("app_auth_token", "<-- 请填写应用授权令牌 -->");

        AlipayTradeQueryResponse response = alipayClient.execute(request);
        System.out.println(response.getBody());

        if (response.isSuccess()) {
            System.out.println("调用成功");
        } else {
            System.out.println("调用失败");
            // sdk版本是"4.38.0.ALL"及以上,可以参考下面的示例获取诊断链接
            // String diagnosisUrl = DiagnosisUtils.getDiagnosisUrl(response);
            // System.out.println(diagnosisUrl);
        }

        return response.getBody();
    }
    //以上是当面付

    //以下是网站支付

    /**
     * 电脑网站支付
     *
     * @param id
     * @param price
     * @param title
     * @return
     * @throws AlipayApiException
     */
    public String computerWebsite(String id, String price, String title) throws AlipayApiException {
        // 初始化SDK
        AlipayClient alipayClient = new DefaultAlipayClient(url, appid, privateKey, "json", "UTf-8", alipayPublicKey, "RSA2");

        // 构造请求参数以调用接口
        AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();

        // 设置回调地址
        request.setNotifyUrl(notifyUrl);

        JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no", id);
        bizContent.put("total_amount", price);
        bizContent.put("subject", title);
        bizContent.put("product_code", "FACE_TO_FACE_PAYMENT");
        request.setBizContent(bizContent.toString());
        request.setBizContent(bizContent.toString());

        // 如果需要返回GET请求，请使用
        AlipayTradePagePayResponse response = alipayClient.pageExecute(request, "GET");

        String pageRedirectionData = response.getBody();

        return pageRedirectionData;
    }


}

